package com.tarena.lbs.marketing.web.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tarena.lbs.marketing.web.repository.CouponCodeRepository;
import com.tarena.lbs.marketing.web.repository.CouponRepository;
import com.tarena.lbs.marketing.web.repository.MarketingActivityRepository;
import com.tarena.lbs.marketing.web.service.MarketingActivityService;
import com.tarena.lbs.marketing.web.service.UserReceiveCouponService;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.BasePageList;
import com.tarena.lbs.basic.api.UserGroupApi;
import com.tarena.lbs.common.attach.enums.BusinessTypeEnum;
import com.tarena.lbs.common.marketing.enums.CouponCodeStatusEnum;
import com.tarena.lbs.common.marketing.enums.ReceiveChannelEnum;
import com.tarena.lbs.common.marketing.enums.MarketingResultEnum;
import com.tarena.lbs.pojo.attach.dto.AttachDTO;
import com.tarena.lbs.pojo.attach.query.AttachQuery;
import com.tarena.lbs.pojo.basic.vo.UserVO;
import com.tarena.lbs.pojo.marketing.bo.CouponBO;
import com.tarena.lbs.pojo.marketing.bo.CouponCodeBO;
import com.tarena.lbs.pojo.marketing.bo.MarketingActivityBO;
import com.tarena.lbs.pojo.marketing.bo.UserReceiveCouponBO;
import com.tarena.lbs.pojo.marketing.param.CouponCodeParam;
import com.tarena.lbs.pojo.marketing.param.MarketingActivityParam;
import com.tarena.lbs.pojo.marketing.param.UpdateParam;
import com.tarena.lbs.pojo.marketing.param.UserReceiveCouponParam;
import com.tarena.lbs.pojo.marketing.query.MarketingActivityQuery;
import com.tarena.lbs.pojo.stock.bo.CouponStockBO;
import com.tarena.lbs.pojo.stock.param.CouponStockParam;
import com.tarena.lbs.stock.api.CouponStockApi;
import io.seata.spring.annotation.GlobalTransactional;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Service
@Slf4j
public class MarketingActivityServiceImpl implements MarketingActivityService {

    @Resource
    private MarketingActivityRepository marketingActivityRepository;

    @Resource
    private CouponRepository couponRepository;

    @Resource
    private AttachApi attachApi;

    @Resource
    private UserGroupApi userGroupApi;

    @Resource
    private CouponStockApi couponStockApi;

    @Resource
    private CouponCodeRepository couponCodeRepository;

    @Resource
    private UserReceiveCouponService userReceiveCouponService;

    /*@Resource
    private TriggerMessageApi triggerMessageApi;*/

    @Value("${app.attach.url}")
    private String url;

    @Override
    public void updateStatus(UpdateParam updateParam) {
        marketingActivityRepository.updateStatus(updateParam);
    }

    @Override
    public void insert(MarketingActivityParam param) throws BusinessException {
        marketingActivityRepository.insert(param);
    }

    @Override
    public void update(MarketingActivityParam param) throws BusinessException {
        marketingActivityRepository.update(param);

    }

    @Override
    public BasePageList<MarketingActivityBO> list(MarketingActivityQuery query) {
        return marketingActivityRepository.list(query);
    }

    @Override
    public List<MarketingActivityBO> selectListByStatus() {
        return marketingActivityRepository.selectListByStatus();
    }

    @Override
    public void batchUpdateActivityStatus(List<UpdateParam> params) {
        marketingActivityRepository.batchUpdateActivityStatus(params);
    }

    @Override
    public MarketingActivityBO getDetail(Integer activityId) {
        //查询图片
        AttachQuery attachQuery = new AttachQuery();
        attachQuery.setBusinessType(BusinessTypeEnum.ACTIVITY.getType());
        attachQuery.setBusinessId(activityId);
        List<AttachDTO> attachInfo = attachApi.getAttachInfoByParam(attachQuery);
        List<String> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(attachInfo)) {
            attachInfo.forEach(attach -> result.add(url + attach.getFileUuid()));
        }
        //查询活动
        MarketingActivityBO marketingActivityBO = marketingActivityRepository.getDetail(activityId);
        marketingActivityBO.setImgPics(result);
        return marketingActivityBO;
    }

    /**
     * 获取店铺最近的活动
     */
    @Override
    @GlobalTransactional
    public MarketingActivityBO handleMessage(String message) throws Exception {
        log.info("开始消费消息 message={}",message);
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(message);
        Integer userId = rootNode.get("userId").asInt();
        Integer storeId = rootNode.get("storeId").asInt();
        //用户合法性校验
        UserVO userVO = userGroupApi.getUser(userId);
        if (userVO == null) {
            throw new BusinessException(MarketingResultEnum.USER_ERROR);
        }
        //店铺合法性
        //找店铺的进行中活动
        MarketingActivityBO marketingActivityBO = marketingActivityRepository.getActivityByStoreId(storeId);
        if (marketingActivityBO == null) {
            throw new BusinessException(MarketingResultEnum.ACTIVITY_NOT_FIND);
        }
        log.info("handleMessage marketingActivityBO={}", JSONObject.toJSONString(marketingActivityBO));
        //用户是否有资格
        if (!StringUtils.isEmpty(marketingActivityBO.getTargetCustomer())) {
            boolean userCanReceive = userGroupApi.isUserInTargetGroup(userId, marketingActivityBO.getTargetCustomer());
            if (!userCanReceive) {
                throw new BusinessException(MarketingResultEnum.USER_GROUP_ERROR);
            }
        }
        //校验优惠券
        CouponBO couponBO = couponRepository.getDetail(marketingActivityBO.getRewardCouponId());
        if (couponBO == null) {
            throw new BusinessException(MarketingResultEnum.COUPON_NOT_FIND);
        }
        //校验优惠券库存
        CouponStockBO couponStockBO = couponStockApi.getCouponStock(marketingActivityBO.getRewardCouponId());
        if (couponStockBO == null || couponStockBO.getNum() <= 0) {
            throw new BusinessException(MarketingResultEnum.COUPON_NOT_CAPACITY);
        }
        //获取券码
        CouponCodeBO couponCodeBO = couponCodeRepository.getCouponCodeDetail(marketingActivityBO.getRewardCouponId());
        if (couponCodeBO == null) {
            throw new BusinessException(MarketingResultEnum.COUPON_NOT_CAPACITY);
        }
        //校验是否发放过
        List<UserReceiveCouponBO> userCouponList = userReceiveCouponService.userCouponList(userId,marketingActivityBO.getRewardCouponId());
        if (!CollectionUtils.isEmpty(userCouponList) && couponBO.getUsageLimit() != 0 && userCouponList.size() >= couponBO.getUsageLimit() ) {
            throw new BusinessException(MarketingResultEnum.USER_GRANT_ERROR);
        }
        //领取优惠券
        UserReceiveCouponParam param = new UserReceiveCouponParam();
        param.setCouponCode(couponCodeBO.getCouponCode());
        param.setUserId(userId);
        param.setActivityId(marketingActivityBO.getId());
        param.setCouponId(marketingActivityBO.getRewardCouponId());
        param.setShopId(storeId);
        param.setReceiveChannel(ReceiveChannelEnum.GRANT.getCode());
        userReceiveCouponService.insert(param);
        //券码状态变更
        CouponCodeParam couponCodeParam = new CouponCodeParam();
        couponCodeParam.setId(couponCodeBO.getId());
        couponCodeParam.setStatus(CouponCodeStatusEnum.DISABLE.getCode());
        couponCodeRepository.update(couponCodeParam);
        //优惠券数量扣减
        CouponStockParam stockParam = new CouponStockParam();
        stockParam.setNum(1);
        stockParam.setCouponId(param.getCouponId());
        couponStockApi.updateCouponStock(stockParam);
        /*RegisterTriggerMessageParam triggerMessageParam = new RegisterTriggerMessageParam();
        triggerMessageParam.setUserId(String.valueOf(userId));
        triggerMessageParam.setUsername(userVO.getUserName());
        triggerMessageParam.setUserAction("优惠券发放");
        triggerMessageParam.setActivityId(marketingActivityBO.getId());
        triggerMessageApi.sendMessage(triggerMessageParam);*/
        return marketingActivityBO;
    }
}
